home *** CD-ROM | disk | FTP | other *** search
/ PC-Blue - MS DOS Public Domain Library / PC-Blue MS-DOS Public Domain Library - NYACC.iso / vol194 / kermasm.arc / MSCMD.ASM next >
Encoding:
Assembly Source File  |  1985-11-14  |  32.4 KB  |  1,118 lines

  1. ; Edit history:
  2.  
  3. ; [v2.28]
  4. ; Fixed up '?' a bit - don't jump into next field before seeing
  5. ; a separator at the end of a keyword.
  6. ; JD 15 May 1985
  7.  
  8.      public comnd, cmcfrm, prserr, repars, cmgtch, drives, comand, fcbcpy
  9.     public cmgetc
  10.     include msdefs.h
  11.  
  12. datas     segment    public 'datas'
  13.     extrn    flags:byte, trans:byte, fcb:byte, buff:byte
  14.     extrn    taklev:byte, takadr:word, dosnum:byte
  15.  
  16. comand    cmdinfo    <>
  17. cmer00  db      cr,lf,'?Program error   Invalid COMND call$'
  18. cmer01  db      cr,lf,'?Ambiguous$'
  19. cmer02  db      cr,lf,'?Illegal input file spec$'
  20. cmer03    db    cr,lf,'?Invalid command$'         ; [19e]
  21. cmer04    db    cr,lf,'?Invalid command or operand$'     ; [1]
  22. cmer06    db    cr,lf,'?Wildcard not allowed$'         ; [21a]
  23. cmer07    db    cr,lf,'?Invalid drive specificaton$'     ; [21a]
  24. cmin00  db      ' Confirm with carriage return$'
  25. cmin01    db    ' One of the following:',cr,lf,'$'
  26.  
  27. cmthlp    dw    0        ; Text of help message for random input.
  28. drives    db    0        ; How many drives we have. [21a]
  29. crlf    db      cr,lf,'$'
  30. ctcmsg    db    '¬C$'
  31. prsp    db    ' $'            ; Print a space.
  32. hlpmsg    dw    0            ; Address of help message.
  33. spchar    db    24H,26H,23H,40H,21H,25H,27H,28H,29H,2DH
  34.     db    3CH,3EH,7BH,7DH,5FH,5CH,5EH,7EH,7CH,60H
  35. spclen    equ    $-spchar
  36. spchar2    db    24H,26H,23H,40H,21H,25H,27H,28H,29H,2DH
  37.     db    7BH,7DH,5FH,5EH,7EH,60H
  38. spc2len    equ    $-spchar2
  39. escspc    db    10O,' ',10O,'$'        ; Clear escape.
  40. clrspc  db      ' ',10O,'$'             ; Clear space.
  41. filbuf  db    60H DUP(?)        ; Character buffer.
  42. tbuff    db    80  DUP(?)
  43. cmdstk    dw    ?
  44. datas    ends
  45.  
  46. code    segment    public
  47.     extrn    dodel:near, ctlu:near, cmblnk:near, locate:near, takrd:near
  48.     extrn    clearl:near
  49.     assume    cs:code,ds:datas,es:datas
  50.  
  51. ;       This routine parses the specified function in AH. Any additional
  52. ;       information is in DX and BX.
  53. ;       Returns +1 on success
  54. ;               +4 on failure (assumes a JMP follows the call)
  55.  
  56. CMND    PROC NEAR
  57. comnd:  mov comand.cmstat,ah    ; Save what we are presently parsing.
  58.     mov cmdstk,sp        ; save stack ptr locally.
  59.         call cminbf             ; Get chars until an action or a erase char.
  60.     mov ah,comand.cmstat    ; Restore 'ah' for upcoming checks.
  61.         cmp ah,cmcfm            ; Parse a confirm?
  62.         jz cmcfrm               ; Go get one.
  63.         cmp ah,cmkey            ; Parse a keyword?
  64.     jnz cm1
  65.         jmp cmkeyw               ; Try and get one.
  66. cm1:    cmp ah,cmifi        ; Parse an input file spec?
  67.     jnz cm2
  68.     jmp cmifil        ; Go get one.
  69. cm2:    cmp ah,cmofi        ; Output file spec?
  70.     jnz cm3
  71.     jmp cmofil        ; Go get one.
  72. cm3:    cmp ah,cmtxt        ; Parse arbitrary text.   [8]
  73.     jnz cm4
  74.     jmp cmtext
  75. cm4:    mov ah,prstr        ; Else give error.
  76.     mov dx,offset cmer00    ; "?Unrecognized COMND call"
  77.     int dos
  78.     ret
  79.  
  80. ; This routine gets a confirm.
  81.  
  82. cmcfrm: call cmgtch        ; Get a char.
  83.     cmp ah,0        ; Is it negative (a terminator; a space or
  84.                 ; a tab will not be returned here as they
  85.                 ; will be seen as leading white space.)
  86.         js cmcfr0
  87.     mov comand.cmstat,cmcfm-1 ; make sure status isn't = cmcfm
  88.         ret                     ; If not, return failure.
  89. cmcfr0: and ah,7FH                      ; Turn off the minus bit.
  90.         cmp ah,esc                      ; Is it an escape?
  91.         jne cmcfr2
  92.         mov ah,conout
  93.         mov dl,bell             ; Get a bell.
  94.         int dos
  95.         mov comand.cmaflg,0    ; Turn off the action flag.
  96.         mov bx,comand.cmcptr    ; Move the pointer to before thee scape.
  97.         dec bx
  98.         mov comand.cmcptr,bx
  99.         mov comand.cmdptr,bx
  100.         dec comand.cmccnt       ; Decremrnt the char count.
  101.         jmp cmcfrm              ; Try again.
  102. cmcfr2: cmp ah,'?'              ; Curious?
  103.         jne cmcfr3
  104.         mov ah,prstr            ; Print something useful.
  105.         mov dx,offset cmin00
  106.         int dos
  107.         mov ah,prstr
  108.         mov dx,offset crlf      ; Print a crlf.
  109.         int dos
  110.         mov ah,prstr
  111.         mov dx,comand.cmprmp    ; Reprint the prompt.
  112.         int dos
  113.         mov bx,comand.cmdptr    ; Get the pointer into the buffer.
  114.         mov ah,'$'              ; Put a $ there for printing.
  115.         mov [bx],ah
  116.         mov bx,comand.cmcptr
  117.         dec bx                  ; Decrement & save the buffer pointer.
  118.         mov comand.cmcptr,bx
  119.         mov ah,prstr
  120.         mov dx,offset comand.cmdbuf
  121.         int dos
  122.         mov ah,0                        ; Turn off the action flag.
  123.         mov comand.cmaflg,ah
  124.         jmp repars              ; Reparse everything.
  125.  
  126. cmcfr3: cmp ah,ff                       ; Is it a form feed?
  127.         jne cmcfr4
  128.         call cmblnk             ; If so blank the screen.
  129. cmcfr4: jmp rskp
  130.  
  131. ;       This routine parses a keyword from the table pointed
  132. ;       to in DX.  The format of the table is as follows:
  133. ;
  134. ;       addr:   db      n       ; Where n is the # of entries in the table.
  135. ;               db      m       ; M is the size of the keyword.
  136. ;               db      'string$' ; Where string is the keyword.
  137. ;               dw      ab      ; Where ab is data to be returned.
  138. ;
  139. ;       The keywords must be in alphabetical order.
  140.  
  141.  
  142. cmkeyw: mov comand.cmhlp,bx     ; Save the help.
  143.         mov comand.cmptab,dx    ; Save the beginning of keyword table.
  144.         mov bx,dx
  145.         mov ch,[bx]             ; Get number of entries in table.
  146.         inc bx
  147.     mov dx,comand.cmdptr    ; Save command pointer.
  148.     mov comand.cmsptr,dx    ; Save pointer's here.
  149. cmky1:  cmp ch,0                ; Any commands left to check?
  150.         jne cmky2
  151.     jmp cmky41        ; no, go complain
  152. cmky2:  dec ch
  153.     mov cl,0        ; Keep track of how many chars read in so far.
  154.         call cmgtch             ; Get a char.
  155.         cmp ah,0                ; Do we have a terminator?
  156.         jns cmky2x 
  157.     jmp cmky4               ; Negative number means we do.
  158. cmky2x: inc bx                  ; Point to first letter of keyword.
  159.     inc cl            ; Read in another char.
  160.         mov al,[bx]                   
  161.         cmp ah,'a'              ; Less than a?
  162.         jl cmky21               ; If so, don't capitalize.
  163.         cmp ah,'z'+1            ; More than z?
  164.         jns cmky21
  165.         and ah,137O             ; Capitalize the letter.
  166. cmky21: cmp ah,al
  167.     je cmky3
  168.     jg cmky2y
  169.         jmp cmky41              ; Fail if ah preceeds al alphabetically.
  170. cmky2y: jmp cmky6               ; Not this keyword - try the next.
  171. cmky3:  inc bx                  ; We match here, how 'bout next char?
  172.         mov al,[bx]
  173.         cmp al,'$'               ; End of keyword?
  174.     jne cmky3x
  175.         jmp cmky7                ; Succeed.
  176. cmky3x:    mov dl,al        ; Save al's char here.
  177.         call cmgtch
  178.     inc cl            ; Read in another char.
  179.     mov al,dl
  180.     cmp ah,'a'
  181.     jl cmky31
  182.     cmp ah,'z'+1
  183.     jns cmky31
  184.     and ah,137O
  185. cmky31: cmp ah,esc+80H        ; Escape Recognition (escape w/minus bit on)?
  186.     je cmky3y
  187.     cmp ah,' '+80H        ; A space?
  188.     je cmky3y
  189.     cmp ah,cr+80H        ; Carriage return?
  190.     je cmky3y
  191.     cmp ah,'?'+80H        ; A question mark?    [3]
  192.     je cmky3y
  193.     jmp cmky38
  194. cmky3y:    mov comand.cmkptr,bx    ; Save bx here.
  195.     mov comand.cmsiz,cx    ; Save size info.
  196.     mov comand.cmchr,ah    ; Save char for latter.
  197.     cmp ah,'?'+80h        ; question mark?
  198.     je cmkyj1        ; yes, always print possibilities
  199.     call cmambg        ; See if input is ambiguous or not.
  200.      jmp cmky32        ; Succeeded (not ambiguous).
  201.     mov ah,comand.cmchr
  202.     cmp ah,esc+80H        ; Escape?
  203.     je cmky3z
  204. ;    cmp ah,'?'+80H        ; maybe question mark?
  205. ;    je cmkyj1        ; yes, go handle
  206.     jmp cmky41        ; Else fail.
  207. cmky3z:    mov ah,conout        ; Ring a bell.
  208.     mov dl,bell
  209.     int dos
  210.     mov bx,comand.cmcptr    ; Move pointer to before the escape.
  211.     dec bx
  212.     mov comand.cmcptr,bx
  213.     mov comand.cmdptr,bx
  214.     dec comand.cmccnt    ; Decrement char count.
  215.     mov bx,comand.cmkptr    ; Failed - pretend user never typed ....
  216.     mov cx,comand.cmsiz    ; ... in a char.
  217.     dec cl            ; Don't count the escape.
  218.     dec bx
  219.     mov comand.cmaflg,0    ; Reset the action flag.
  220.     jmp cmky3        ; Keep checking.
  221. ; ambiguous.  Print out all the keywords that match
  222. cmkyj1:    mov dx,offset cmin01
  223.     mov ah,prstr
  224.     int dos
  225.     mov bx,comand.cmkptr    ; this is current keyword
  226.     mov cx,comand.cmsiz    ; we are cl chars into it
  227.     mov ch,0
  228.     sub bx,cx        ; back up to beginning
  229.     inc bx            ; not counting ?
  230.     mov comand.cmkptr,bx    ; save beginning of kw
  231. cmkyj2:    mov dl,tab        ; put a tab before each keyword
  232.     mov ah,conout
  233.     int dos
  234.     mov dx,comand.cmkptr    ; get current keyword
  235.     mov ah,prstr
  236.     int dos            ; print it
  237.     mov bx,comand.cmkptr    ; get keyword back
  238.     dec bx
  239.     mov al,[bx]        ; get length
  240.     mov ah,0
  241.     add ax,5        ; skip length, $, value, next length
  242.     add bx,ax        ; this is next keyword
  243.     mov si,bx
  244.     mov di,comand.cmkptr    ; compare with last keyword
  245.     mov comand.cmkptr,bx    ; update this
  246.     mov cx,comand.cmsiz
  247.     dec ch            ; are we at end of table?
  248.     jl cmkyj3        ; yes, don't go on
  249.     mov comand.cmsiz,cx    ; else update count
  250.     mov ch,0
  251.     dec cl            ; this includes ?
  252.     jcxz cmkyj2        ; empty, just print it
  253.     repe cmpsb        ; compare to previous string
  254.     je cmkyj2        ; same, go print this one
  255. cmkyj3:    jmp cmky50        ; else go finish up
  256.  
  257. cmky32: mov cx,comand.cmsiz    ; Restore info.
  258.     mov bx,comand.cmkptr    ; Our place in the keyword table.
  259.     cmp comand.cmchr,' '+80H ; Space?
  260.     je cmky35
  261.     cmp comand.cmchr,'?'+80H ; Question mark?
  262.     je cmky35
  263.     cmp comand.cmchr,cr+80H    ; Carriage return?
  264.     je cmky35
  265.     dec comand.cmcptr    ; Pointer into buffer of input.
  266.     mov dx,comand.cmcptr
  267. cmky33:    mov ah,[bx]        ; Get next char in keyword.
  268.     cmp ah,'$'        ; Are we done yet?
  269.     jz cmky34
  270.     mov di,dx
  271.     mov [di],ah
  272.     inc bx
  273.     inc dx
  274.     inc comand.cmccnt
  275.     jmp cmky33
  276. cmky34:    mov ah,' '
  277.     mov di,dx
  278.     mov [di],ah        ; Put a blank in the buffer.
  279.     inc dx
  280.     mov cx,comand.cmcptr    ; Remember where we were.
  281.     mov comand.cmcptr,dx    ; Update our pointers.
  282.     mov comand.cmdptr,dx
  283.     mov ah,'$'
  284.     mov di,dx
  285.     mov [di],ah        ; Add '$' for printing.
  286.     mov ah,prstr
  287.     mov dx,cx        ; Point to beginning of filled in data.
  288.     int dos
  289.     inc bx            ; Point to address we'll need.
  290.     mov bx,[bx]
  291.     mov comand.cmaflg,0    ; Turn off action flag.
  292.     jmp rskp
  293.  
  294. cmky35:    inc bx
  295.     mov ah,[bx]        ; Find end of keyword. 
  296.     cmp ah,'$'
  297.     jne cmky35    
  298.     inc bx
  299.     mov bx,[bx]        ; Address of next routine to call.
  300. ;    mov comand.cmaflg,0    ; Zero the action flag.
  301.     jmp rskp
  302.  
  303. cmky38:    cmp ah,al
  304.     je cmky39
  305.         jmp cmky6               ; Go to end of keyword and try next.
  306. cmky39:    jmp cmky3        ; Check next letter.
  307.            
  308. cmky4:  and ah,7FH              ; Turn off minus bit.
  309.         cmp ah,'?'              ; Need help?
  310.         je cmky5
  311.     cmp ah,' '        ; Just a space - no error.
  312.     je cmky51
  313.     cmp ah,cr
  314.     je cmky51
  315.     cmp ah,tab
  316.     je cmky51 
  317.     cmp ah,esc        ; Ignore escape?
  318.     je cmky43
  319. cmky41: mov ah,prstr
  320.         mov dx,offset cmer03
  321.         int dos
  322.         jmp prserr              ; Parse error - give up.
  323.  
  324. cmky43:    mov ah,conout        ; Ring a bell.
  325.     mov dl,bell
  326.     int dos
  327.     dec comand.cmcptr    ;[ESC] don't trash BX here.
  328.     dec comand.cmdptr    ;[ESC] ditto
  329.     dec comand.cmccnt    ; Don't count the escape.
  330.     mov comand.cmaflg,0    ; Reset action flag.
  331.     inc ch            ; Account for a previous 'dec'.
  332.     jmp cmky1        ; Start over.
  333.  
  334. cmky5:    inc bx            ; point to actual keyword
  335.     mov comand.cmkptr,bx    ; remember current kw
  336.     mov cl,1        ; code above expects to count ?
  337.     mov comand.cmsiz,cx    ; and size
  338.     mov dx,comand.cmhlp
  339.     or dx,dx        ; was any help given?
  340.     jnz cmky5a        ; yes, use it
  341.     jmp cmkyj1        ; else make our own message
  342. cmky5a:    mov ah,prstr
  343.         int dos
  344. cmky50:    mov ah,prstr
  345.     mov dx,offset crlf
  346.     int dos
  347.     mov dx,comand.cmprmp    ; Address of prompt.
  348.     int dos
  349.     mov bx,comand.cmdptr    ; Get pointer into buffer.
  350.     mov al,'$'
  351.     mov [bx],al        ; Add dollar sign for printing.
  352.     mov dx,offset comand.cmdbuf
  353.     int dos
  354.     dec comand.cmcptr    ; Don't keep it in the buffer.
  355.     dec comand.cmccnt    ; Don't conut it.
  356.     mov comand.cmaflg,0     ; Turn off the action flag.
  357.         jmp repars
  358.  
  359. cmky51:    cmp comand.cmcr,1    ; Are bare CR's allowed?
  360.     je cmky52        ; Yes.
  361.     mov ah,prstr
  362.     mov dx,offset cmer04    ; Complain.
  363.     int dos
  364. cmky52:    jmp prserr
  365.  
  366. cmky6:  inc bx                  ; Find end of keyword.
  367.     cmp byte ptr [bx],'$'
  368.         jne cmky6             
  369.     add bx,3                  ; Beginning of next command.
  370.     mov dx,comand.cmsptr    ; Get old cmdptr.
  371.     mov comand.cmdptr,dx    ; Restore.
  372.     mov comand.cmsflg,0FFH
  373.         jmp cmky1               ; Keep trying.
  374.  
  375. cmky7:  call cmgtch             ; Get char.
  376.     cmp ah,0
  377.     js cmky71        ; Ok if a terminator.
  378.         dec bx
  379.         jmp cmky6               ; No match - try next keyword.
  380. cmky71:    cmp ah,'?'+80h        ; question mark?
  381.     jne cmky72        ; yes, don't return yet
  382.     dec bx            ; back up over '$'
  383.     jmp cmky3y        ; and process ? correctly
  384. cmky72:    inc bx                  ; Get necessary data.
  385.         mov bx,[bx]
  386.     cmp ah,esc+80h        ; An escape?
  387.     jne cmky73
  388.     mov ah,prstr
  389.     mov dx,offset prsp      ; Print a space.
  390.     int dos
  391.     mov di,comand.cmcptr
  392.     dec di
  393.     mov ah,20H
  394.     mov [di],ah        ; Replace escape char with space.
  395.     mov comand.cmaflg,0
  396.     mov comand.cmsflg,0FFH    ; Pretend they typed a space.
  397. cmky73:    jmp rskp
  398.  
  399. ; See if keyword is unambiguous or not from what the user has typed in.
  400.  
  401. cmambg:    cmp ch,0        ; Any keywords left to check?
  402.     jne cmamb0
  403.     ret            ; If not then not ambiguous.
  404. cmamb0:    inc bx            ; Go to end of keyword ...
  405.     mov al,[bx]        ; So we can check the next one.
  406.     cmp al,'$'
  407.     jne cmamb0
  408.     add bx,4        ; Point to start of next keyword.
  409.     dec cl            ; Don't count escape.
  410.     mov dx,comand.cmsptr    ; Buffer with input typed by user.
  411. cmamb1:    mov ah,[bx]        ; Keyword char.    
  412.     mov di,dx
  413.     mov al,[di]        ; Input char.
  414.     cmp al,'a'        ; Do capitalizing.
  415.     jl cmam11
  416.     cmp al,'z'+1
  417.     jns cmam11
  418.     and al,137O
  419. cmam11:    cmp ah,al        ; Keyword bigger than input (alphabetically)?
  420.     jle cmamb2        ; No - keep checking.
  421.     ret            ; Yes - not ambiguous.
  422. cmamb2:    inc bx            ; Advance one char.
  423.     inc dx
  424.     dec cl
  425.     jnz cmamb1
  426.     jmp rskp        ; Fail - it's ambiguous.
  427.  
  428. cmifil:    mov hlpmsg,bx        ; Address of help message.
  429.     mov bx,dx               ; Get the fcb address in bx.
  430.         mov comand.cmfcb,bx     ; Save it.
  431.         mov ch,0                ; Initialize char count.
  432.         mov ah,0
  433.         mov [bx],ah        ; Set the drive to default to current.
  434.     inc bx
  435.         mov comand.cmfcb2,bx
  436.         mov cl,' '
  437. cmifi0: mov [bx],cl        ; Blank the FCB.
  438.         inc bx
  439.         inc ah
  440.         cmp ah,0BH        ; Twelve?
  441.         jl cmifi0
  442. cmifi1: call cmgtch             ; Get another char.
  443.         cmp ah,0                ; Is it an action character.
  444.     js cmif1x        ; Jump out of range. [21a]
  445.         jmp cmifi2        ; Ditto. [21a]
  446. cmif1x: and ah,7FH              ; Turn off the action bit. [21a]
  447.         cmp ah,'?'              ; A question mark?
  448.         jne cmif12
  449.         mov al,0
  450.         mov comand.cmaflg,al    ; Blank the action flag.
  451.         dec comand.cmcptr       ; Decrement the buffer pointer.
  452.     dec comand.cmccnt    ; Decrement count.
  453.     mov ah,prstr
  454.     mov dx,hlpmsg        ; Help  message.
  455.     int dos
  456.     mov dx,offset crlf
  457.     int dos
  458.     mov dx,comand.cmprmp
  459.     int dos
  460.     mov bx,comand.cmdptr
  461.     mov al,'$'
  462.     mov [bx],al        ; Put in dollar sign for printing.
  463.     mov dx,offset comand.cmdbuf
  464.     int dos
  465.     jmp repars
  466. cmif12: cmp ah,esc        ; An escape?
  467.     je cm12x
  468.         jmp cmif13
  469. cm12x:    mov comand.cmaflg,0    ; Turn off the action flag.
  470.     dec comand.cmcptr    ; Move pointers to before the escape.
  471.     dec comand.cmdptr
  472.     dec comand.cmccnt    ; Decrement char count.
  473.     mov comand.cmchr,ch    ; Save current character count.
  474.     cmp ch,9        ; Past '.'?
  475.          jl cmf120        ; No.
  476.     dec ch            ; Yes, don't count point.
  477. cmf120:    mov di,comand.cmfcb2    ; Fill the rest with CP/M wildcards.
  478.     mov ah,'?'
  479.  
  480. cmf121:    cmp ch,11        ; Done?
  481.      jge cmf122        ; Yes.
  482.     mov [di],ah
  483.     inc di
  484.     inc ch
  485.     jmp cmf121
  486.  
  487. cmf122: mov ah,sfirst        ; Find first matching file?
  488.     mov dx,comand.cmfcb    ;[jd] use pointer to PASSED fcb
  489.     int dos
  490.     cmp al,0FFH        ; Any found?
  491.     jne cmf123        ; Yes.
  492.      jmp cmf12b        ; No, lose.
  493. cmf123:    mov di,offset filbuf    ; Copy first file spec from DTA to buffer.
  494.     mov bx,offset buff+1
  495.     mov cl,11
  496.     call fcbcpy
  497.     mov di,offset filbuf+10H ; Get another copy (if not ambiguous).
  498.     mov bx,offset buff+1
  499.     mov cl,11
  500.     call fcbcpy
  501.     mov ah,snext        ; More matching specs?
  502.     mov dx,comand.cmfcb    ;[jd] use PASSED fcb...
  503.     int dos
  504.     cmp al,0FFH
  505.      je cmf124        ; Only one.
  506.     mov di,offset filbuf+10H ; Copy second file spec.
  507.     mov bx,offset buff+1
  508.     mov cl,11
  509.     call fcbcpy
  510.  
  511. cmf124:    mov si,offset filbuf    ; Start comparing file names.
  512.     mov bx,offset filbuf+10H
  513.     mov di,comand.cmcptr    ; Command buffer pointer
  514.     mov cl,comand.cmchr    ; Bypass characters typed.
  515.     cmp cl,9        ; Past '.'?
  516.      jl cmf125        ; No.
  517.     dec cl            ; Yes, don't count point.
  518. cmf125:    mov ch,0        ; Adjust pointers.
  519.     add si,cx
  520.     add bx,cx
  521.     mov ch,cl        ; Update character count
  522.  
  523. cmf126:    cmp ch,11        ; All done?
  524.     jne cmf127        ; No.
  525.      jmp cmf12a        ; Yes.
  526. cmf127:    cmp ch,8        ; End of file name?
  527.      jne cmf128        ; No.
  528.     cmp comand.cmchr,9    ; Exactly at point?
  529.      je cmf128        ; Yes, don't output a second point.
  530.     mov ah,'.'        ; Output separator.
  531.     mov [di],ah
  532.     inc di
  533.     inc comand.cmccnt
  534. cmf128:    mov ah,[si]        ; Get a character from first file spec.
  535.     inc si
  536.     mov al,[bx]        ; Get another from second spec.
  537.     inc bx
  538.     cmp ah,al        ; Compare.
  539.      jne cmf12a        ; Ambiguous.
  540.     inc ch            ; Same, count.
  541.     cmp ah,' '        ; Blank?
  542.      je cmf129        ; Yes, don't output.
  543.     mov [di],ah
  544.     inc di
  545.     inc comand.cmccnt
  546. cmf129:    jmp cmf126        ; Repeat.
  547.  
  548. cmf12a:    mov comand.cmchr,ch    ; Save count of characters processed.
  549.     mov ah,'$'        ; Put terminator into buffer.
  550.     mov [di],ah
  551.     mov comand.cmcptr,di    ; Save pointer for recognized characters.
  552.     mov ah,prstr
  553.     mov dx,comand.cmdptr
  554.     int dos
  555.     mov ch,comand.cmchr    ; Characters processed.
  556.     cmp ch,11        ; Complete file name.
  557.      je cmf12c        ; Yes, don't beep.
  558.  
  559. cmf12b:    mov ah,conout        ; Beep, if not recognized.
  560.     mov dl,bell
  561.     int dos            ; Ring the bell.
  562. cmf12c:    jmp repars
  563.  
  564. cmif13: mov ah,ch               ; It must be a terminator.
  565.         cmp ah,0                ; Test the length of the file name.
  566.     jnz cmf3x
  567.     cmp comand.cmcr,1    ; Is zero length OK? [21a]
  568.     je cmf3z        ; Return successfully. [21a]
  569.         jmp cmifi9              ; If zero complain.
  570. cmf3x:  cmp ah,0DH
  571.         js cmf3y
  572.     jmp cmifi9              ; If too long complain.
  573. cmf3y:  jmp rskp                ; Otherwise we have succeeded.
  574. cmf3z:    push es
  575.     mov ax,ds
  576.     mov es,ax
  577.     mov di,comand.cmfcb
  578.     inc di
  579.     mov cx,11
  580.     mov al,'?'
  581.     repne stosb
  582.     pop es
  583.     mov flags.wldflg,0FFH    ; Remember we had a wildcard.
  584.     jmp rskp
  585. cmifi2: cmp ah,'.'
  586.         jne cmifi3
  587.         inc ch
  588.         cmp ch,1H        ; Any chars yet?
  589.           jnz cmf2x
  590.     jmp cmifi9        ; No, give error.
  591. cmf2x:  cmp ch,0AH        ; Tenth char?
  592.           js cmf2y
  593.     jmp cmifi9              ; Past it, give an error.
  594. cmf2y:  mov dl,9H
  595.         mov dh,0
  596.         mov bx,comand.cmfcb
  597.         add bx,dx               ; Point to file type field.
  598.         mov comand.cmfcb2,bx
  599.         mov ch,9H               ; Say we've gotten nine.
  600.         jmp cmifi1              ; Get the next char.
  601. cmifi3: cmp ah,':'
  602.         jne cmifi4
  603.         inc ch
  604.         cmp ch,2H        ; Is it in right place for a drive?
  605.     je cmif3x
  606.         jmp cmifi9              ; If not, complain.
  607. cmif3x: mov ch,0        ; Reset char count.
  608.     mov flags.droflg,1    ; Override default drive. [21a]
  609.     mov flags.nmoflg,0    ; Not so fast. [21a]
  610.     mov bx,comand.cmfcb2
  611.     mov al,':'        ; Use for parsing drive name.
  612.     mov [bx],al
  613.     dec bx            ; Point to drive spec.
  614.     mov si,bx
  615.     push es
  616.     mov ax,ds
  617.     mov es,ax
  618.     mov di,offset tbuff    ; Borrow this buffer.
  619.     mov ah,prsfcb
  620.     int dos
  621.     pop es
  622.     cmp al,0        ; OK return code?
  623.     je cmif3y        ; Yes, keep going.
  624. ;        mov ah,[bx]        ; Get the drive name.
  625. ;        sub ah,'@'              ; Get the drive number.
  626. ;    cmp ah,drives        ; Did user specify a non-existant drive? [21a]
  627. ;    jle cmif3y        ; Nope, so continue. [21a]
  628.     mov dx,offset cmer07    ; Fail with this error message. [21a]
  629.     jmp cmif9x        ; [21a]
  630. cmif3y:    mov comand.cmfcb2,bx    ; Put rest of filename starting here. [21a]
  631.     mov ah,[bx]        ; Pick up drive specified.
  632.     sub ah,'@'        ; Get real value.
  633.      mov bx,comand.cmfcb
  634.         mov [bx],ah        ; Put it in the fcb.
  635.     push bx
  636.     mov al,' '        ; Overwrite the drive and ":".
  637.     inc bx
  638.     mov [bx],al
  639.     inc bx
  640.     mov [bx],al
  641.     pop bx
  642.         jmp cmifi1
  643. cmifi4: cmp ah,'*'
  644.         jne cmifi7
  645.     cmp comand.cmrflg,1    ; In receive mode?  [21a]
  646.     jne cmif4x        ; Jump out of range. [21a]
  647.     mov dx,offset cmer06    ; Set the error message. [21a]
  648.     jmp cmif9x            ; Fail - no wildcard allowed. [21a]
  649. cmif4x: mov ah,ch        ; [21a]
  650.         cmp ah,8H        ; Is this in the name or type field?
  651.         jns cmifi5              ; Type.
  652.         mov cl,8H               ; Say we have eight chars.
  653.         js cmifi6        ; Name field.
  654.         jmp cmifi9        ; If its where the dot should be give up.
  655. cmifi5: mov cl,0CH              ; Three chars.
  656. cmifi6: mov flags.wldflg,0FFH    ; Remember we had a wildcard.
  657.     mov bx,comand.cmfcb2    ; Get a pointer into the FCB.
  658.         mov ah,'?'
  659.         mov [bx],ah        ; Put a question mark in.
  660.         inc bx
  661.         mov comand.cmfcb2,bx
  662.         inc ch
  663.         mov ah,ch
  664.         cmp ah,cl
  665.         jl cmifi6               ; Go fill in another.
  666.         jmp cmifi1              ; Get the next char.
  667. cmifi7: cmp ah,03DH        ; Equals sign (wildcard)?
  668.     jne cmif7x
  669.     cmp comand.cmrflg,1    ; In receive mode?  [21a]
  670.     jne cmif7y        ; No, so it's ok. [21a]
  671.     mov dx,offset cmer06    ; Set the error message. [21a]
  672.     jmp cmif9x        ; Fail - no wildcard allowed. [21a]
  673. cmif7y:    mov ah,'?'        ; New label. [21a]
  674.     mov flags.wldflg,0FFH    ; Say we have a wildcard.
  675.     jmp cmifi8        ; Put into FCB.
  676. cmif7x:    cmp ah,'0'
  677.         jl cmif8x
  678.         cmp ah,'z'+1
  679.         jns cmif8x
  680.         cmp ah,'A'        ; Don't capitalize non-alphabetics.
  681.         jl cmifi8
  682.         and ah,137O             ; Capitalize.
  683. cmifi8: mov bx,comand.cmfcb2    ; Get the pointer into the FCB.
  684.         mov [bx],ah             ; Put the char there.
  685.         inc bx
  686.         mov comand.cmfcb2,bx
  687.     mov flags.nmoflg,1    ; Overriding name from host. [21a]
  688.         inc ch
  689.         jmp cmifi1
  690.  
  691. cmif8x:    push cx
  692.     push es
  693.     mov cx,ds
  694.     mov es,cx        ; Scan uses ES register.
  695.     mov di,offset spchar    ; Special chars.
  696.     mov cx,spclen        ; How many of them.
  697.     cmp dosnum,0        ; Under version 2.0
  698.     je cmif8y
  699.     mov di,offset spchar2
  700.     mov cx,spc2len
  701. cmif8y:    mov al,ah        ; Char is in al.
  702.     repne scasb        ; Search string for input char.
  703.     pop es
  704.     pop cx
  705.     je cmifi8        ; found in table, ok
  706.  
  707. cmifi9: mov dx,offset cmer02
  708. cmif9x:    mov ah,prstr
  709.         int dos
  710.     mov flags.droflg,0    ; Not overriding drive. [21a] 
  711.     mov flags.nmoflg,0    ; Or name to save file under. [21a]
  712.     mov comand.cmrflg,0    ; Reset this flag too. [21a]
  713.         ret
  714.  
  715. cmofil: jmp cmifil              ; For now, the same as CMIFI.
  716.  
  717. ; Parse arbitrary text up to a CR.  Put chars into data buffer sent to
  718. ; the host (pointed to by BX).   Called with text of help message in DX.
  719. ; Return updated pointer in BX and input size in AH.
  720.  
  721. cmtext:    mov comand.cmptab,bx    ; Save pointer to data buffer.   [8 start]
  722.     mov cmthlp,dx        ; Save the help message.
  723.     mov cl,0        ; Init the char count.
  724. cmtxt1:    mov comand.cmsflg,0    ; Get all spaces. [25]
  725.     call cmgtch        ; Get a char.
  726.     test ah,80H        ; is high-order bit on?
  727.     jz cmtxt5        ; Nope, put into the buffer.
  728.     and ah,07FH
  729.     cmp ah,' '
  730.     je cmtxt5
  731.     cmp ah,esc        ; An escape?
  732.     jne cmtxt2
  733.     mov ah,conout
  734.     mov dl,bell        ; Ring a bell.
  735.     int dos
  736.     mov comand.cmaflg,0    ; Reset action flag.
  737.     dec comand.cmcptr    ; Move pointer to before the escape.
  738.     dec comand.cmdptr
  739.     dec comand.cmccnt    ; Decrement count.
  740.     jmp cmtxt1        ; Try again.
  741. cmtxt2:    cmp ah,'?'        ; Asking a question?
  742.     jz cmtx30
  743.     cmp ah,ff        ; Formfeed?
  744.     jne cmtx2x
  745.     call cmblnk
  746. cmtx2x: mov ah,cl        ; Return count in AH.
  747.     mov bx,comand.cmptab    ; Return updated pointer.
  748.     jmp rskp
  749. cmtx30:    mov comand.cmaflg,0    ; Reset action flag to zero.
  750.     inc comand.cmdptr    ; count the ?
  751.     cmp cl,0        ; Is "?" first char?
  752.     jne cmtxt5        ; No, just add to buffer.
  753.     dec comand.cmcptr    ;[ESC] (moved 3 lines) Don't keep in buffer.
  754.     dec comand.cmccnt    ;[ESC] Don't conut it.
  755.     dec comand.cmdptr    ;[ESC] don't count if printing help.
  756.     mov ah,prstr        ; Else, give some help.
  757.     mov dx,cmthlp        ; Address of help message.
  758.     int dos
  759.         mov ah,prstr
  760.         mov dx,offset crlf      ; Print a crlf.
  761.         int dos
  762.         mov ah,prstr
  763.         mov dx,comand.cmprmp    ; Reprint the prompt.
  764.     int dos
  765.     mov bx,comand.cmdptr    ; Get the pointer into the buffer.
  766.     mov byte ptr [bx],'$'
  767.     mov ah,prstr
  768.     mov dx,offset comand.cmdbuf
  769.     int dos
  770.     jmp cmtxt1        ; And keep going.
  771. cmtxt5: inc cl            ; Increment the count.
  772.     mov bx,comand.cmptab    ; Pointer into destination array.
  773.     mov [bx],ah        ; Put char into the buffer.
  774.     inc bx
  775.     mov comand.cmptab,bx
  776.     jmp cmtxt1                    ; [8 end]
  777.  
  778. cmgetc:    cmp taklev,0
  779.     jne cmget1
  780.     jmp cmge10            ; no take file, get from keyboard
  781. cmget1:    push bx
  782.     push si
  783.     mov bx,takadr
  784.     mov ax,[bx].takcnt
  785.     or ax,[bx].takcnt+2
  786.     jnz cmget5
  787. cmget2:    mov al,byte ptr [bx].takfcb    ; get first byte of fcb
  788.     cmp al,0ffh            ; is it really a macro?
  789.     je cmget4            ; yes, better not try to close it
  790.     cmp al,0feh            ; or maybe a file handle?
  791.     je cmget3            ; yes, close w/2.0 call
  792.     mov ah,closf
  793.     lea dx,[bx].takfcb
  794.     int dos
  795.     jmp short cmget4            ; skip over alternate close
  796. cmget3:    mov bx,word ptr [bx].takfcb+1    ; this is where file handle is stored
  797.     mov ah,close2            ; use 2.0 close
  798.     int dos
  799. cmget4:    dec taklev
  800.     sub takadr,size takinfo
  801.     pop si
  802.     pop bx
  803.     mov al,cr        ; end with carriage return...
  804.     ret
  805.     
  806. cmget5:    cmp [bx].takchl,0    ; Any chars left in buffer?
  807.     jne cmget6
  808.     call takrd
  809. cmget6:    dec [bx].takchl
  810.     sub [bx].takcnt,1    ; DEC doesn't set carry!!
  811.     sbb [bx].takcnt+2,0
  812.     mov si,[bx].takptr
  813.     lodsb
  814.     mov [bx].takptr,si
  815.     cmp al,ctlz        ; maybe control-z?
  816.     je cmget2        ; yes, close take file (has to be before pops)
  817.     pop si
  818.     pop bx
  819.     cmp al,lf        ; linefeed?
  820.     jne cmget7
  821.     jmp cmgetc        ; yes, ignore it.
  822. cmget7:    cmp al,';'        ; maybe a semicolon?
  823.     je cmget9
  824.     cmp flags.takflg,0    ; Echo contents of take file?
  825.     je cmget8
  826.     push dx
  827.     mov dl,al
  828.     mov ah,conout
  829.     int dos
  830.     pop dx
  831. cmget8:    ret            ; else just return...
  832. ; semicolon seen, ignore chars until cr
  833. cmget9:    call cmgetc        ; get a character?
  834.     cmp al,cr        ; carriage return?
  835.     jne cmget9        ; no, keep reading
  836.     ret            ; else return it
  837.  
  838. cmge10:    mov ah,coninq        ; Get a char.
  839.     cmp flags.debug,0    ; in debug mode?
  840.     je cmge11        ; yes, go on
  841.     mov ah,8        ; else use read that recognizes ¬C
  842. cmge11:    int dos
  843.     and al,7fh        ; only allow 7-bit characters.
  844.     push ax            ; save the char
  845.     cmp al,del
  846.     je cmgex
  847.     cmp al,' '        ; printable?
  848.     jae cmge12        ; yes, no translation needed
  849.     cmp al,cr        ; this is printable
  850.     je cmge12
  851.     cmp al,lf
  852.     je cmge12
  853.     cmp al,tab
  854.     je cmge12
  855. cmgex:    mov al,' '        ; else echo a space
  856. cmge12:    mov dl,al        ; put char here
  857.     cmp comand.cmquiet,0    ; quiet mode?
  858.     jnz cmge13        ; yes, skip echoing...
  859.     mov ah,conout
  860.     int dos            ; echo it ourselves...
  861. cmge13:    pop ax            ; and return it
  862.     cmp al,'C'-40H        ; control-C?
  863.     je cmge15        ; yes, go handle
  864.     cmp al,tab
  865.     jne cmge14
  866.     mov al,' '
  867. cmge14:    ret
  868. cmge15:    mov dx,offset ctcmsg
  869.     mov ah,prstr
  870.     int dos
  871.     mov flags.cxzflg,'C'    ; remember ¬C'd
  872.     mov sp,cmdstk        ; restore command stack ptr
  873.     ret            ; and fail
  874.  
  875. ; Come here is user types ¬W when during input.
  876. cntrlw:    mov ah,prstr
  877.     mov dx,offset escspc
  878.     int dos
  879.     dec comand.cmccnt    ; Don't include it in the count.
  880.     dec comand.cmcptr    ; Back up past the ¬W.
  881.     mov cl,comand.cmccnt
  882.     mov ch,0
  883.     jcxz ctlw2
  884.     pushf 
  885.     push es
  886.     std            ; Scan backwards.
  887.     mov ax,ds
  888.     mov es,ax        ; Point to the data area.
  889.     mov di,comand.cmcptr    ; Looking from here.
  890.     dec di
  891.     mov al,' '
  892.     repe scasb        ; Look for non-space.
  893.     je ctlw1        ; All spaces, nothing else to do
  894.     inc di            ; move back to non-space
  895.     inc cx
  896.     repne scasb        ; look for a space
  897.     jne ctlw1        ; no space, leave ptrs alone
  898.     inc di
  899.     inc cx            ; skip back over space
  900. ctlw1:    inc di
  901.     mov comand.cmccnt,cl    ; update count
  902.     mov cx,comand.cmcptr    ; remember old ptr
  903.     mov comand.cmcptr,di    ; update pointer
  904.     sub cx,di        ; this is characters moved
  905.     mov al,bs        ; backspace
  906.     cld
  907.     mov di,offset tbuff    ; temporary buffer
  908.     rep stosb        ; put enough spaces in
  909.     mov byte ptr [di],'$'    ; end buffer
  910.     mov dx,offset tbuff
  911.     mov ah,prstr
  912.     int dos            ; back up cursor
  913.     call clearl        ; clear line
  914.     pop es
  915.     popf
  916.     ret            ; and return
  917. ctlw2:    mov ah,conout
  918.     mov dl,bell
  919.     int dos
  920.     ret
  921.  
  922. cminbf:    push dx
  923.     push bx
  924.     mov cx,dx        ; Save value here too.
  925.     mov ah,comand.cmaflg    ; Is the action char flag set?
  926.     cmp ah,0
  927.     je cminb1
  928.     jmp cminb9        ; If so get no more chars.
  929. cminb1: inc comand.cmccnt    ; Increment the char count.
  930.     call cmgetc
  931.     mov ah,al        ; Keep char in 'ah'.
  932.     mov bx,comand.cmcptr    ; Get the pointer into the buffer.
  933.     mov [bx],ah        ; Put it in the buffer.
  934.     inc bx
  935.     mov comand.cmcptr,bx
  936.     cmp ah,'W'-64        ; Is it a ¬W?
  937.     jne cmnb11
  938.     call cntrlw        ; Kill the previous word.
  939.     jmp repars
  940. cmnb11:    cmp ah,25O        ; Is it a ¬U?
  941.     jne cminb2
  942. cmnb12: call ctlu        ; Clear out the line.
  943.     mov ah,prstr
  944.     mov dx,comand.cmprmp    ; Print the prompt.
  945.     int dos
  946.     mov bx,offset comand.cmdbuf
  947.     mov comand.cmcptr,bx    ; Reset the point to the start.
  948.     mov comand.cmccnt,0    ; Zero the count.
  949.     mov dx,cx        ; Preserve original value of dx.
  950.     jmp repars        ; Go start over.
  951. cminb2: cmp ah,bs           ; Or backspace?
  952.     jz cminb3
  953.     cmp ah,del        ; Delete?
  954.     jne cminb4
  955. cminb3:    call dodel        ; Delete a character.
  956.     mov ah,comand.cmccnt    ; Decrement the char count by two.
  957.     dec ah
  958.     dec ah
  959.     cmp ah,0            ; Have we gone too far?
  960.     jns cmnb32        ; If not proceed.
  961.     mov ah,conout        ; Ring the bell.
  962.     mov dl,bell
  963.     int dos
  964.     jmp cmnb12        ; Go reprint prompt and reparse.
  965. cmnb32: mov comand.cmccnt,ah    ; Save the new char count.
  966.     mov ah,prstr        ; Erase the character.
  967.     mov dx,offset clrspc
  968.     int dos
  969.     mov bx,comand.cmcptr    ; Get the pointer into the buffer.
  970.     dec bx            ; Back up in the buffer.
  971.     dec bx
  972.     mov comand.cmcptr,bx
  973.     jmp repars        ; Go reparse everything.
  974. cminb4: cmp ah,'?'        ; Is it a question mark.
  975.     jz cminb6
  976.     cmp ah,esc        ; Is it an escape?
  977.     jz cminb8
  978.     cmp ah,cr        ; Is it a carriage return?
  979.     jz cminb5
  980.     cmp ah,lf        ; Is it a line feed?
  981.     jz cminb5
  982.     cmp ah,ff        ; Is it a formfeed?
  983.     jne cminb7
  984.     call cmblnk
  985.     call locate
  986. cminb5: mov ah,comand.cmccnt    ; Have we parsed any chars yet?
  987.     cmp ah,1
  988.     jnz cminb6
  989.     jmp prserr        ; If not, just start over.
  990. cminb6: mov ah,0FFH        ; Set the action flag.
  991.     mov comand.cmaflg,ah
  992.     jmp cminb9
  993. cminb7: jmp cminb1        ; Get another char.
  994.  
  995. cminb8: mov ah,prstr        ; Don't print the escape char.
  996.     mov dx,offset escspc
  997.     int dos
  998.     jmp cminb6
  999.  
  1000. cminb9: pop bx
  1001.     pop dx
  1002.     ret
  1003.  
  1004. cmgtch: push cx
  1005.     push bx
  1006.     push dx
  1007. cmgtc1: mov ah,comand.cmaflg
  1008.     cmp ah,0            ; Is it set.
  1009.     jne cmgt10
  1010.     call cminbf        ; If the action char flag is not set get more.
  1011. cmgt10: mov bx,comand.cmdptr    ; Get a pointer into the buffer.
  1012.     mov ah,[bx]        ; Get the next char.
  1013.     inc bx
  1014.     mov comand.cmdptr,bx
  1015.     cmp ah,' '        ; Is it a space?
  1016.     jz cmgtc2
  1017.     cmp ah,tab        ; Or a tab?
  1018.     jne cmgtc3
  1019. cmgtc2: mov ah,comand.cmsflg    ; Get the space flag.
  1020.     cmp ah,0        ; Was the last char a space?
  1021.     jne cmgtc1        ; Yes, get another char.
  1022.     mov ah,0FFH        ; Set the space flag.
  1023.     mov comand.cmsflg,ah
  1024.     mov ah,' '
  1025.     pop dx
  1026.     pop bx
  1027.     jmp cmgtc5
  1028. cmgtc3: mov al,0
  1029.     mov comand.cmsflg,al    ; Zero the space flag.
  1030.     pop dx
  1031.     pop bx
  1032.     cmp ah,esc
  1033.     jz cmgtc5
  1034.     cmp ah,'?'        ; Is the user curious?
  1035.     jz cmgtc4
  1036.     cmp ah,cr
  1037.     jz cmgtc4
  1038.     cmp ah,lf
  1039.     jz cmgtc4
  1040.     cmp ah,ff
  1041.     je cmgtc4
  1042.     pop cx
  1043.     ret            ; Not an action char, just return.
  1044. cmgtc4: dec comand.cmdptr
  1045. cmgtc5: or ah,80H        ; Make the char negative to indicate
  1046.     pop cx
  1047.     ret            ; it is a terminator.
  1048. CMND    ENDP
  1049.  
  1050. ;    This address is jumped to on reparse.
  1051.  
  1052. PARSE    PROC NEAR 
  1053. repars: mov sp,comand.cmostp   ; new sp <-- old sp
  1054.     mov bx,offset comand.cmdbuf
  1055.     mov comand.cmdptr,bx
  1056.     mov ah,0FFH
  1057.     mov comand.cmsflg,ah
  1058.     jmp comand.cmrprs    ; go back to reparse address 
  1059.  
  1060. ;    This address can be jumped to on a parsing error.
  1061.  
  1062. prserr: mov sp,comand.cmostp    ; Set new sp to old one.
  1063.     mov bx,offset comand.cmdbuf
  1064.     mov comand.cmcptr,bx    ; Initialize the command pointer.
  1065.     mov comand.cmdptr,bx
  1066.     mov ah,0
  1067.     mov comand.cmaflg,ah    ; Zero the flags.
  1068.     mov comand.cmccnt,ah
  1069.     mov comand.cmsflg,0FFH
  1070.     cmp taklev,0        ; in take cmd?
  1071.     jne prser1        ; yes, don't print prompt
  1072.     mov ah,prstr
  1073.     mov dx,offset crlf
  1074.     int dos
  1075.     mov ah,prstr        ; Print the prompt.
  1076.     mov dx,comand.cmprmp    ; Get the prompt.
  1077.     int dos
  1078. ; Instead return to before the prompt call.
  1079. prser1:    jmp comand.cmrprs
  1080. PARSE    ENDP
  1081.  
  1082. ;    FCB must be remembered if found "*" in filename.      [7 start]
  1083. ;     Copy from place addressed by BX to place addressed by DI.
  1084. ;    Also use to get the filename to the FCB from the DTA.
  1085.  
  1086. FCBCPY    PROC    NEAR
  1087.     push    es
  1088.     push    si
  1089.     mov    ax,ds
  1090.     mov    es,ax        ; make sure destination segment is correct
  1091.     mov    ch,0        ; high-order part of length
  1092.     jcxz    fcbcp1        ; zero argument (is this necessary???)
  1093.     mov    si,bx        ; this is source
  1094.     rep    movsb        ; copy the whole thing
  1095. fcbcp1:    pop    si
  1096.     pop    es
  1097.     ret            ; and return
  1098. FCBCPY    ENDP    
  1099.  
  1100. ; Jumping to this location is like retskp.  It assumes the instruction
  1101. ;   after the call is a jmp addr.
  1102.  
  1103. RSKP    PROC    NEAR
  1104.     pop bp
  1105.     add bp,3
  1106.     push bp
  1107.     ret
  1108. RSKP    ENDP
  1109.  
  1110. ; Jumping here is the same as a ret.
  1111.  
  1112. R    PROC    NEAR
  1113.     ret
  1114. R    ENDP
  1115.  
  1116. code    ends
  1117.     end
  1118.